#include <stdio.h>
#include <string.h>
#include "abplayer.h"


using namespace Connect5;


static int board[16][16] = {
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
};


static bool rb_first = false;
static int cur_role = 1;
static int cur_x = -1;
static int cur_y = -1;

void show(void)
{
	int i,j,piece;
  	puts("  A B C D E F G H I J K L M N O");
  	for(i=0; i<15; i++) {
  		printf("%c ",i+97);
    	for(j=0; j<15; j++) {
      		if(piece=board[i][j]) 
            {
                if(i == cur_x && j == cur_y)
                {
        		    printf("\033[1;31m%c\033[0m ",piece==1?'X':'O');
                }
                else
                {
        		    printf("%c ",piece==1?'X':'O');
                }
      		} else { 
                printf(". ");
            }
        }
    	putchar('\n');
  	}
}

//@ret
// 1: role win
// 0: playing
// -1: role lose
static int check_board(int role, const ABPlayer &rbt)
{
    int black_score = rbt.black_score();
    printf("current black_score:%d\n", black_score);
    if(black_score == min_score)
    {
        return role==1 ?-1: 1;
    }
    else if(black_score == max_score)
    {
        return role==1 ?1: -1;
    }
    return 0;
}

static bool translate_step(char &r, char &c)
{
    if('A' <= r && r <= 'O')
    {
        r -= 'A';
    }
    else if( 'a' <= r &&  r <= 'o')
    {
        r -= 'a';
    }
    else
    {
        return false;
    }
    if('A' <= c && c <= 'O')
    {
        c -= 'A';
    }
    else if( 'a' <= c &&  c <= 'o')
    {
        c -= 'a';
    }
    else
    {
        return false;
    }
    return true;

}

//@ret: bool: is legal step
static bool check_step(int x, int y)
{
    return  0 <= x && x < 15 && 0 <= y && y < 15 && 0 == board[x][y];
}

void play_with_computer()
{
    int rd = rand();
    if(rd & 0x1) //首盘机器先手
    {
        rb_first = true;
    }
    else
    {
        rb_first = false;

    }
    rb_first = false;
    ABPlayer rbt;
    while(true)
    {
        char r = -1, c = -1, a = -1;
        int sret = 0;
        show();
        int cbt =  check_board(cur_role, rbt); // check board result
        if(cbt == 1)
        {
            if(cur_role ==1 ^ rb_first) 
            { //cur_role is human
LABEL_YOU_WIN:                
                puts("You win!!!");
LABEL_ASK_AGAIN:
                puts("Again?(Y/N):");
                scanf("%c", &a);
                while(getchar() != '\n');
                if(a == 'Y' || a == 'y')
                {
                    rb_first = !rb_first;
                    rbt.clear();
                    cur_role =1;
                    memset(board, 0, sizeof(board));    
                    continue;
                }
                else
                {
                    return;
                }
            }
            else
            { //cur_role is robot
LABEL_YOU_LOSE:
                puts("You lose!!!");
                goto LABEL_ASK_AGAIN;
            }
        }
        else if(cbt == -1)
        {
            if(cur_role ==1 ^ rb_first) 
            { //cur_role is human
                goto LABEL_YOU_LOSE; 
            }
            else
            { //cur_role is robot
                goto LABEL_YOU_WIN;
            }
        }
        
        if(cur_role ==1 ^ rb_first) 
        { //cur_role is human
LABEL_TRY_AGAIN:
            printf("Input your step(Eg: jH):");
            sret =  scanf("%c%c", &r, &c);
            while(getchar() != '\n');
            if(r == '-')
            {
                switch(c)
                {
                case 'h': //help
                    goto LABEL_RBT_THK;      
                    break;
                case 'r':  //reverse role
                    rb_first = !rb_first;
                    goto LABEL_RBT_THK;      
                    break;
                default:
                    break;
                }
            }
            if(2 != sret || !translate_step(r, c) || !check_step(r ,c))
            {
                printf("Invalid step, please try again!\n");
                goto LABEL_TRY_AGAIN;
            }
            cur_x = r; cur_y = c;
        }
        else
        { //cur_role is robot
LABEL_RBT_THK:
            puts("The robot is thinking...");
            rbt.think(6);
            rbt.get_next(cur_x, cur_y);
            if(!check_step(cur_x, cur_y))
            {
                puts("DRAW!!!");
                goto LABEL_ASK_AGAIN;
            }
        }
        board[cur_x][cur_y] = cur_role;
        rbt.goahead(cur_x, cur_y);
        rbt.show();
        cur_role = cur_role==1 ? 2 : 1;

    }
}


int main()
{
    play_with_computer();
    return 0;
}
